home *** CD-ROM | disk | FTP | other *** search
- Path: abcfd20.larc.nasa.gov!amiga-request
- From: amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
- Subject: v90i244: ListPlot - 2d plotting program, Part03/03
- Reply-To: Anthony M. Richardson <amr@dukee.egr.duke.edu>
- Newsgroups: comp.sources.amiga
- Message-ID: <comp.sources.amiga:v90i244@abcfd20.larc.nasa.gov>
- Date: 23 Aug 90 01:03:49 GMT
- Approved: tadguy@uunet.UU.NET (Tad Guy)
- X-Mail-Submissions-To: amiga@uunet.uu.net
- X-Post-Discussions-To: comp.sys.amiga
-
- Submitted-by: Anthony M. Richardson <amr@dukee.egr.duke.edu>
- Posting-number: Volume 90, Issue 244
- Archive-name: applications/listplot/part03
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 3 (of 3)."
- # Contents: Csrc/plotting.c
- # Wrapped by tadguy@abcfd20 on Wed Aug 22 21:03:22 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Csrc/plotting.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Csrc/plotting.c'\"
- else
- echo shar: Extracting \"'Csrc/plotting.c'\" \(25452 characters\)
- sed "s/^X//" >'Csrc/plotting.c' <<'END_OF_FILE'
- X/*
- X * plotting.c
- X *
- X * plotting routines.
- X *
- X */
- X#include <stdio.h>
- X#include <errno.h>
- Xextern int errno;
- X#include <assert.h>
- X#include <string.h>
- X#include <ctype.h>
- X#include <signal.h>
- X#include "datatypes.h"
- X
- Xvoid ErrorExit();
- X
- X#ifndef min
- X# define min(A,B) A<B? A : B
- X#endif
- X#ifndef max
- X# define max(A,B) A>B? A : B
- X#endif
- X
- Xextern bool GraphicsInProgress;
- X
- X/* GoldenRatio = (1+Sqrt(5))/2 */
- X#define GOLDENRATIO 1.6180339887499
- X#define ASPECTRATIO 1.0/GOLDENRATIO
- Xextern VALUE V_AngularUnit;
- Xextern VALUE V_AnnotationScale;
- Xextern VALUE V_AspectRatio;
- Xextern VALUE V_Boxed;
- Xextern VALUE V_Domain;
- Xextern VALUE V_Gridding;
- Xextern VALUE V_LabelScale;
- Xextern VALUE V_LineColor;
- Xextern VALUE V_LineStyle;
- Xextern VALUE V_Orientation;
- Xextern VALUE V_Origin;
- Xextern VALUE V_PlotColor;
- Xextern VALUE V_PlotDevice;
- Xextern VALUE V_PlotJoined;
- Xextern VALUE V_PlotPoints;
- Xextern VALUE V_PlotTitle;
- Xextern VALUE V_PlotType;
- Xextern VALUE V_PointScale;
- Xextern VALUE V_PointSymbol;
- Xextern VALUE V_PolarVariable;
- Xextern VALUE V_Range;
- Xextern VALUE V_SubPages;
- Xextern VALUE V_SupplyAbscissa;
- Xextern VALUE V_TitleScale;
- Xextern VALUE V_UseInputFile;
- Xextern VALUE V_Verbose;
- Xextern VALUE V_ViewPort;
- Xextern VALUE V_XLabel;
- Xextern VALUE V_XTick;
- Xextern VALUE V_YLabel;
- Xextern VALUE V_YTick;
- X
- Xchar *DeviceTypes[] = {
- X "amiga",
- X "printer",
- X "iff",
- X "hp",
- X "aegis",
- X "postscript",
- X (char *)NULL
- X};
- X
- Xtypedef struct line_style {
- X int ls_type;
- X int ls_nelms;
- X int *ls_space;
- X int *ls_mark;
- X } LINESTYLE;
- XLIST LineStyleList;
- XLINESTYLE *LineStyles; int NLineStyles;
- Xint *PointCodes, NPointCodes;
- Xint space0 = 0, mark0 = 0, space1 = 1500, mark1 = 1500;
- X
- XRECT UserRect;
- XRECT ViewPort = { 0.1,0.1, 0.9,0.9 };
- XRECT WorldRect = {0.0,0.0, 1.0,1.0};
- X
- X
- Xvoid
- XListPlot(Data, NTuples, TupleSize)
- XFLOAT **Data;
- Xint NTuples, TupleSize;
- X{
- X void InitializeDevice();
- X void InitializePlottingEnv();
- X#ifdef ANSI_C
- X void Plot2D(FLOAT **, int , int );
- X void PolarPlot(FLOAT **, int , int );
- X#else
- X void Plot2D();
- X void PolarPlot();
- X#endif
- X
- X InitializeDevice();
- X GraphicsInProgress = TRUE;
- X
- X InitializePlottingEnv(Data, NTuples, TupleSize);
- X
- X if (Vstrcmp(V_PlotType,"polar")) {
- X PolarPlot(Data, NTuples, TupleSize);
- X } else {
- X Plot2D(Data, NTuples, TupleSize);
- X }
- X plend();
- X}
- X
- X
- Xvoid
- XInitializeDevice()
- X{
- X register int i;
- X register char *DeviceStr;
- X
- X
- X plorient(Vstrcmp(V_Orientation, "portrait")? 1 : 0);
- X plselect(stdout); /* write to stdout */
- X
- X
- X DeviceStr = V_PlotDevice.val_u.udt_string;
- X for (i=0; DeviceTypes[i]; i++)
- X if (strcmp(DeviceStr, DeviceTypes[i]) == 0) {
- X plbeg(
- X i+1, /* device code */
- X (int)V_SubPages.val_u.udt_interval.int_lo, /* nx */
- X (int)V_SubPages.val_u.udt_interval.int_hi /* ny */
- X );
- X return;
- X }
- X fprintf(stderr,"(InitializeDevice) Unknown device type: %s\n", DeviceStr);
- X ErrorExit();
- X}
- X
- Xvoid
- XInitializePlottingEnv(Data, NTuples, TupleSize)
- XFLOAT **Data;
- Xint NTuples;
- Xint TupleSize;
- X{
- X int i, j;
- X FLOAT *Ptr;
- X void InitLineStyles();
- X void InitPointCodes();
- X
- X /* viewport */
- X ViewPort = VtoRect(V_ViewPort);
- X
- X /* user window */
- X UserRect.XMin = MAX_FLOAT;
- X UserRect.YMin = MAX_FLOAT;
- X UserRect.XMax = -MAX_FLOAT;
- X UserRect.YMax = -MAX_FLOAT;
- X
- X if (VtoBoolean(V_SupplyAbscissa)) {
- X UserRect.XMin = 0.0;
- X UserRect.XMax = (FLOAT)(NTuples-1);
- X } else {
- X for (i=0; i<NTuples; i++) {
- X if (Data[i][0] < UserRect.XMin)
- X UserRect.XMin = Data[i][0];
- X if (Data[i][0] > UserRect.XMax)
- X UserRect.XMax = Data[i][0];
- X }
- X }
- X for (i=0; i<NTuples; i++)
- X for (j=TupleSize-1,Ptr= &Data[i][1]; j>0; --j,Ptr++) {
- X if (*Ptr < UserRect.YMin)
- X UserRect.YMin = *Ptr;
- X if (*Ptr > UserRect.YMax)
- X UserRect.YMax = *Ptr;
- X }
- X
- X
- X /* font scaling */
- X
- X /* plot type */
- X
- X /* grid */
- X
- X /* line styles */
- X InitLineStyles();
- X
- X
- X /* line colors */
- X
- X /* point symbols */
- X InitPointCodes();
- X
- X /* window type */
- X
- X /* X label */
- X
- X /* Y label */
- X
- X /* Plot title */
- X
- X /* aspect ratio */
- X}
- X
- X#define isMark(C) (((C) == 'M' || (C) == 'm')? TRUE : FALSE)
- X#define isSpace(C) (((C) == 'S' || (C) == 's')? TRUE : FALSE)
- X#define MarkLength(C) (C) == 'M'? 1000 : 250
- X#define SpaceLength(C) (C) == 'S'? 1000 : 250
- X#define MAX_MARKS 32
- X
- Xvoid
- XDecodeLineStyle(StyleStr, Mark, Space, N)
- Xchar *StyleStr;
- Xint **Mark;
- Xint **Space;
- Xint *N;
- X{
- X register char *S;
- X int macc, sacc;
- X int i, j, k;
- X int mark[MAX_MARKS];
- X int space[MAX_MARKS];
- X bool ProcessingMark;
- X
- X /*
- X * 'S' = 1000 micron space
- X * 's' = 250 micron space
- X * 'M' = 1000 micron line
- X * 'm' = 250 micron line
- X */
- X ProcessingMark = TRUE; /* to satisfy some compilers */
- X if (isMark(*StyleStr))
- X ProcessingMark = TRUE;
- X else if (isSpace(*StyleStr))
- X ProcessingMark = FALSE;
- X else {
- X fprintf(stderr,"(DecodeLineStyle) Invalid Line style: \"%s\"\n", StyleStr);
- X ErrorExit();
- X }
- X memset((char *)mark, 0, MAX_MARKS * sizeof(int));
- X memset((char *)space, 0, MAX_MARKS * sizeof(int));
- X for (macc=0,sacc=0,i=0,j=0,S=StyleStr ; *S && i<MAX_MARKS && j<MAX_MARKS; ++S) {
- X if (isMark(*S) && ProcessingMark) {
- X macc += MarkLength(*S);
- X } else if (isMark(*S) && !ProcessingMark) {
- X space[j++] = sacc;
- X macc = MarkLength(*S);
- X ProcessingMark = TRUE;
- X } else if (isSpace(*S) && ProcessingMark) {
- X mark[i++] = macc;
- X sacc = SpaceLength(*S);
- X ProcessingMark = FALSE;
- X } else if (isSpace(*S) && !ProcessingMark) {
- X sacc += SpaceLength(*S);
- X } else if (isspace(*S)) {
- X continue;
- X } else {
- X fprintf(stderr,"(DecodeLineStyle) Invalid line style code '%c' in \"%s\"\n", *S, StyleStr);
- X ErrorExit();
- X }
- X }
- X if (ProcessingMark)
- X mark[i++] = macc;
- X else
- X space[j++] = sacc;
- X
- X k = max(i,j);
- X
- X if (((*Mark) = (int *)calloc(k, sizeof(int))) == (int *)NULL) {
- X perror("(DecodeLineStyle) ");
- X ErrorExit();
- X }
- X if (((*Space) = (int *)calloc(k, sizeof(int))) == (int *)NULL) {
- X perror("(DecodeLineStyle) ");
- X ErrorExit();
- X }
- X for (i=0; i<k; i++) {
- X (*Mark)[i] = mark[i];
- X (*Space)[i] = space[i];
- X }
- X *N = k;
- X}
- X
- Xvoid
- XInitLineStyles()
- X{
- X int i;
- X LATOM *A;
- X LINESTYLE *LS;
- X int *Mark, *Space;
- X int N;
- X#ifdef ANSI_C
- X LINESTYLE *LSAlloc(int , int *, int *);
- X#else
- X LINESTYLE *LSAlloc();
- X#endif
- X
- X LineStyleList.list_n = 0;
- X LineStyleList.list_head = (LATOM *)NULL;
- X LineStyleList.list_tail = (LATOM *)NULL;
- X
- X LS = LSAlloc(0, (int *)NULL, (int *)NULL);
- X Append(&LineStyleList, (generic *)LS);
- X
- X for (i=1,A=V_LineStyle.val_u.udt_set.list_head; A; A=A->la_next,i++) {
- X DecodeLineStyle(
- X (char *)A->la_p,
- X &Mark,
- X &Space,
- X &N
- X );
- X LS = LSAlloc(N, Mark, Space);
- X Append(&LineStyleList, (generic *)LS);
- X }
- X
- X NLineStyles = i;
- X if ((LineStyles = (LINESTYLE *)calloc(NLineStyles, sizeof(LINESTYLE))) == (LINESTYLE *)NULL) {
- X perror("(InitLineStyles) ");
- X ErrorExit();
- X }
- X for (i=0,A=LineStyleList.list_head; A; A=A->la_next,i++) {
- X LineStyles[i].ls_mark = ((LINESTYLE *)(A->la_p))->ls_mark;
- X LineStyles[i].ls_space = ((LINESTYLE *)(A->la_p))->ls_space;
- X LineStyles[i].ls_nelms = ((LINESTYLE *)(A->la_p))->ls_nelms;
- X }
- X}
- X
- X
- XLINESTYLE *
- XLSAlloc(n, Mark, Space)
- Xint n;
- Xint *Mark, *Space;
- X{
- X register LINESTYLE *LS;
- X
- X if ((LS = (LINESTYLE *)calloc(1, sizeof(LINESTYLE))) == (LINESTYLE *)NULL) {
- X perror("(LSAlloc) ");
- X assert(LS != (LINESTYLE *)NULL);
- X exit(errno);
- X }
- X LS->ls_mark = Mark;
- X LS->ls_space = Space;
- X LS->ls_nelms = n;
- X return(LS);
- X}
- X
- Xvoid
- XInitPointCodes()
- X{
- X register LATOM *A;
- X register int i;
- X extern int *PointCodes, NPointCodes;
- X extern VALUE V_PointSymbol;
- X
- X if (!isSet(V_PointSymbol)) {
- X NPointCodes = 0;
- X return;
- X }
- X
- X /* count # codes */
- X for (i=0,A=V_PointSymbol.val_u.udt_set.list_head; A; A=A->la_next, i++)
- X ;
- X
- X NPointCodes = i;
- X if (NPointCodes == 0)
- X return;
- X
- X if ((PointCodes = (int *)calloc(NPointCodes, sizeof(int))) == (int *)NULL) {
- X perror("(InitPointCodes) ");
- X assert(PointCodes != (int *)NULL);
- X ErrorExit();
- X }
- X for (i=0,A=V_PointSymbol.val_u.udt_set.list_head; A; A=A->la_next, i++) {
- X PointCodes[i] = atoi((char *)A->la_p);
- X }
- X}
- X
- X
- Xvoid
- XPlot2D(Data, NTuples, TupleSize)
- XFLOAT **Data;
- Xint NTuples;
- Xint TupleSize;
- X{
- X int i, j;
- X FLOAT *X, *Y;
- X FLOAT x, y;
- X FLOAT x0, y0;
- X FLOAT xtick, ytick;
- X FLOAT Xmin,Xmax, Ymin,Ymax;
- X FLOAT MedianX, StdDevX;
- X FLOAT MedianY, StdDevY;
- X int nxsub, nysub;
- X bool AutoRange, AutoDomain;
- X bool LogX, LogY;
- X char Xopt[16], Yopt[16];
- X#ifdef ANSI_C
- X void StatisticsOfX(
- X FLOAT **,
- X int,
- X int ,
- X FLOAT *,
- X FLOAT *
- X );
- X void StatisticsOfY(
- X FLOAT **,
- X int,
- X int ,
- X FLOAT *,
- X FLOAT *
- X );
- X double log10(double);
- X#else
- X void StatisticsOfX();
- X void StatisticsOfY();
- X double log10();
- X#endif
- X
- X pladv(0);
- X ViewPort = VtoRect(V_ViewPort);
- X
- X if (isString(V_AspectRatio)) {
- X /* automatic --> STRETCH */
- X plvpor(ViewPort.XMin, ViewPort.XMax, ViewPort.YMin, ViewPort.YMax);
- X/*debug
- X plvsta();
- Xdebug*/
- X } else {
- X assert(isDbl(V_AspectRatio));
- X plvasp(VtoDbl(V_AspectRatio));
- X }
- X
- X LogX = (Vstrcmp(V_PlotType, "loglin") || Vstrcmp(V_PlotType,"loglog"))?
- X TRUE : FALSE;
- X LogY = (Vstrcmp(V_PlotType, "linlog") || Vstrcmp(V_PlotType,"loglog"))?
- X TRUE : FALSE;
- X
- X /* window bounds */
- X AutoDomain = FALSE;
- X if (isString(V_Domain) && Vstrcmp(V_Domain, "All")) {
- X /* all points */
- X Xmin = UserRect.XMin;
- X Xmax = UserRect.XMax;
- X } else if (isString(V_Domain) && Vstrcmp(V_Domain,"Automatic")) {
- X /* automatic */
- X AutoDomain = TRUE;
- X StatisticsOfX(Data, NTuples, TupleSize, &MedianX, &StdDevX);
- X x = MedianX - 3.0*StdDevX;
- X Xmin = UserRect.XMin < x? x : UserRect.XMin;
- X x = MedianX + 3.0*StdDevX;
- X Xmax = UserRect.XMax > x? x : UserRect.XMax;
- X } else {
- X assert(isInterval(V_Domain));
- X Xmin = V_Domain.val_u.udt_interval.int_lo;
- X Xmax = V_Domain.val_u.udt_interval.int_hi;
- X }
- X if (LogX) {
- X if (Xmin == 0.0 || Xmax == 0.0) {
- X /* error */
- X fprintf(stderr,"ListPlot: Trying to find log10(0) in data! Stop.\n");
- X ErrorExit();
- X }
- X Xmin = log10((double)Xmin);
- X Xmax = log10((double)Xmax);
- X }
- X
- X AutoRange = FALSE;
- X if (isString(V_Range) && Vstrcmp(V_Range, "All")) {
- X /* all */
- X Ymin = UserRect.YMin;
- X Ymax = UserRect.YMax;
- X } else if (isString(V_Range) && Vstrcmp(V_Range,"Automatic")) {
- X /* automatic */
- X AutoRange = TRUE;
- X StatisticsOfY(Data, NTuples, TupleSize, &MedianY, &StdDevY);
- X y = MedianY - 3.0*StdDevY;
- X Ymin = UserRect.YMin < y? y : UserRect.YMin;
- X y = MedianY + 3.0*StdDevY;
- X Ymax = UserRect.YMax > y? y : UserRect.YMax;
- X } else {
- X assert(isInterval(V_Range));
- X Ymin = V_Range.val_u.udt_interval.int_lo;
- X Ymax = V_Range.val_u.udt_interval.int_hi;
- X }
- X if (LogY) {
- X if (Ymin == 0.0 || Ymax == 0.0) {
- X /* error */
- X fprintf(stderr,"ListPlot: Trying to find log10(0) in data! Stop.\n");
- X ErrorExit();
- X }
- X Ymin = log10((double)Ymin);
- X Ymax = log10((double)Ymax);
- X }
- X plwind(
- X Xmin,
- X Xmax,
- X Ymin,
- X Ymax
- X );
- X plschr(0., VtoDbl(V_AnnotationScale));
- X
- X
- X /* X and Y ticks */
- X if (isString(V_XTick)) {
- X /* automatic */
- X xtick = 0.;
- X nxsub = 0;
- X } else {
- X xtick = V_XTick.val_u.udt_interval.int_lo;
- X if (LogX) xtick = log10((double)xtick);
- X nxsub = V_XTick.val_u.udt_interval.int_hi;
- X }
- X if (isString(V_YTick)) {
- X /* automatic */
- X ytick = 0.;
- X nysub = 0;
- X } else {
- X ytick = V_YTick.val_u.udt_interval.int_lo;
- X if (LogY) ytick = log10((double)ytick);
- X nysub = V_YTick.val_u.udt_interval.int_hi;
- X }
- X
- X /* Axis options */
- X Xopt[0] = (char)NULL;
- X Yopt[0] = (char)NULL;
- X if (isBoolean(V_Boxed) && VtoBoolean(V_Boxed)) {
- X strcat(Xopt, "bc");
- X strcat(Yopt, "bc");
- X } else if (isString(V_Boxed)) {
- X if (Vstrchr(V_Boxed, 'b'))
- X strcat(Xopt, "b");
- X if (Vstrchr(V_Boxed, 't'))
- X strcat(Xopt, "c");
- X if (Vstrchr(V_Boxed, 'r'))
- X strcat(Yopt, "c");
- X if (Vstrchr(V_Boxed, 'l'))
- X strcat(Yopt, "b");
- X } else {
- X ;
- X }
- X if (LogX)
- X strcat(Xopt, "l");
- X if (LogY)
- X strcat(Yopt, "l");
- X strcat(Xopt, "nst");
- X strcat(Yopt, "nstv");
- X
- X if (isString(V_Origin) && Vstrcmp(V_Origin, "Median")) {
- X if (AutoDomain == FALSE) {
- X StatisticsOfX(Data,NTuples,TupleSize,&MedianX,&StdDevX);
- X }
- X if (AutoRange == FALSE) {
- X StatisticsOfY(Data,NTuples,TupleSize,&MedianY,&StdDevY);
- X }
- X plaxes(
- X MedianX,MedianY,
- X Xopt, xtick, nxsub,
- X Yopt, ytick,nysub
- X );
- X } else if (isInterval(V_Origin)) {
- X x0 = V_Origin.val_u.udt_interval.int_lo;
- X y0 = V_Origin.val_u.udt_interval.int_hi;
- X plaxes(
- X x0,y0,
- X Xopt, xtick, nxsub,
- X Yopt, ytick,nysub
- X );
- X } else if (isString(V_Origin) && Vstrcmp(V_Origin, "Automatic")) {
- X plbox(Xopt, xtick, nxsub, Yopt, ytick,nysub);
- X } else {
- X plbox(Xopt, xtick, nxsub, Yopt, ytick,nysub);
- X }
- X
- X /* gridding */
- X if (VtoBoolean(V_Gridding)) {
- X /* gridding on */
- X plstyl(1, &mark1, &space1);
- X plbox("g", xtick, nxsub, "g", ytick,nysub);
- X plstyl(0, &mark0, &space0);
- X }
- X
- X /* plot curves */
- X if ((X = (FLOAT *)calloc(NTuples, sizeof(FLOAT))) == (FLOAT *)NULL) {
- X perror("(Plot2D) ");
- X ErrorExit();
- X }
- X if ((Y = (FLOAT *)calloc(NTuples, sizeof(FLOAT))) == (FLOAT *)NULL) {
- X perror("(Plot2D) ");
- X ErrorExit();
- X }
- X if (VtoBoolean(V_SupplyAbscissa)) {
- X for (i=0; i<NTuples; i++)
- X X[i] = LogX? log10((double)(i+1)) : (FLOAT)i;
- X } else {
- X for (i=0; i<NTuples; i++)
- X X[i] = LogX? log10((double)Data[i][0]) : Data[i][0];
- X }
- X for (i=1; i<TupleSize; i++) {
- X if (NLineStyles > 0) {
- X /* use user-supplied patterns */
- X plstyl(
- X LineStyles[(i-1)%NLineStyles].ls_nelms,
- X LineStyles[(i-1)%NLineStyles].ls_mark,
- X LineStyles[(i-1)%NLineStyles].ls_space
- X );
- X } else {
- X pllsty((i-1)%8 + 1);
- X }
- X plcol(i);
- X for (j=0; j<NTuples; j++)
- X Y[j] = LogY? log10((double)Data[j][i]) : Data[j][i];
- X
- X if (VtoBoolean(V_PlotJoined))
- X plline(NTuples, X, Y);
- X
- X if (VtoBoolean(V_PlotPoints)) {
- X plschr(0., VtoDbl(V_PointScale));
- X pllsty(1);
- X if (NPointCodes > 0) {
- X plpoin(NTuples, X, Y, PointCodes[(i-1)%NPointCodes]);
- X } else {
- X plpoin(NTuples, X, Y, i);
- X }
- X }
- X }
- X
- X
- X /* restore line styles etc... */
- X pllsty(1);
- X plcol(1);
- X plschr(0., VtoDbl(V_LabelScale));
- X pllab(VtoString(V_XLabel), VtoString(V_YLabel), "");
- X plschr(0., VtoDbl(V_TitleScale));
- X pllab("","", VtoString(V_PlotTitle));
- X}
- X
- X#define DTR(D) (double)((D)*3.1415927/180.0)
- X
- Xvoid
- XPolarPlot(Data, NTuples, TupleSize)
- XFLOAT **Data;
- Xint NTuples;
- Xint TupleSize;
- X{
- X int i, j;
- X FLOAT *A, *R;
- X FLOAT x, y;
- X FLOAT xtick, ytick;
- X FLOAT atick, rtick;
- X FLOAT Xmin,Xmax, Ymin,Ymax;
- X FLOAT r, rmax, ang, amax;
- X FLOAT MedianX, StdDevX;
- X FLOAT MedianY, StdDevY;
- X FLOAT da;
- X FLOAT x0,y0, xn,yn;
- X double pi;
- X char s[32];
- X int nxsub, nysub, nrsub, nasub;
- X bool InRadians, XisAngular;
- X bool AutoDomain, AutoRange;
- X#ifdef ANSI_C
- X void StatisticsOfX(
- X FLOAT **,
- X int ,
- X int ,
- X FLOAT *,
- X FLOAT *
- X );
- X void StatisticsOfY(
- X FLOAT **,
- X int ,
- X int ,
- X FLOAT *,
- X FLOAT *
- X );
- X double log10(double); double fabs();
- X double sqrt(), sin(), cos(), atan();
- X#else
- X void StatisticsOfX();
- X void StatisticsOfY();
- X double log10(); double fabs();
- X double sqrt(), sin(), cos(), atan();
- X#endif
- X
- X pi = 4.0 * atan((double)1.0);
- X InRadians = Vstrcmp(V_AngularUnit, "degrees")? FALSE : TRUE;
- X XisAngular = Vstrcmp(V_PolarVariable,"angle")? TRUE : FALSE;
- X
- X pladv(0);
- X
- X if (isString(V_AspectRatio)) {
- X /* automatic --> STRETCH */
- X plvasp(1.0);
- X } else {
- X assert(isDbl(V_AspectRatio));
- X plvasp(VtoDbl(V_AspectRatio));
- X }
- X
- X /* window bounds */
- X AutoDomain = FALSE;
- X if (isString(V_Domain) && Vstrcmp(V_Domain, "All")) {
- X /* all points */
- X Xmin = UserRect.XMin;
- X Xmax = UserRect.XMax;
- X } else if (isString(V_Domain) && Vstrcmp(V_Domain,"Automatic")) {
- X /* automatic */
- X AutoDomain = TRUE;
- X StatisticsOfX(Data, NTuples, TupleSize, &MedianX, &StdDevX);
- X x = MedianX - 3.0*StdDevX;
- X Xmin = UserRect.XMin < x? x : UserRect.XMin;
- X x = MedianX + 3.0*StdDevX;
- X Xmax = UserRect.XMax > x? x : UserRect.XMax;
- X } else {
- X assert(isInterval(V_Domain));
- X Xmin = V_Domain.val_u.udt_interval.int_lo;
- X Xmax = V_Domain.val_u.udt_interval.int_hi;
- X }
- X
- X AutoRange = FALSE;
- X if (isString(V_Range) && Vstrcmp(V_Range, "All")) {
- X /* all */
- X Ymin = UserRect.YMin;
- X Ymax = UserRect.YMax;
- X } else if (isString(V_Range) && Vstrcmp(V_Range,"Automatic")) {
- X /* automatic */
- X AutoRange = TRUE;
- X StatisticsOfY(Data, NTuples, TupleSize, &MedianY, &StdDevY);
- X y = MedianY - 3.0*StdDevY;
- X Ymin = UserRect.YMin < y? y : UserRect.YMin;
- X y = MedianY + 3.0*StdDevY;
- X Ymax = UserRect.YMax > y? y : UserRect.YMax;
- X } else {
- X assert(isInterval(V_Range));
- X Ymin = V_Range.val_u.udt_interval.int_lo;
- X Ymax = V_Range.val_u.udt_interval.int_hi;
- X }
- X rmax = XisAngular? Ymax : Xmax;
- X plwind(
- X -1.3*rmax,
- X 1.3*rmax,
- X -1.3*rmax,
- X 1.3*rmax
- X );
- X
- X
- X /* X and Y ticks */
- X if (isString(V_XTick)) {
- X /* automatic */
- X xtick = XisAngular? (InRadians? pi/6.0 : 30.0) : 0.25 * rmax;
- X nxsub = 4;
- X } else {
- X xtick = V_XTick.val_u.udt_interval.int_lo;
- X nxsub = V_XTick.val_u.udt_interval.int_hi;
- X }
- X if (isString(V_YTick)) {
- X /* automatic */
- X ytick = XisAngular? 0.25 * rmax : (InRadians? pi/6.0 : 30.0);
- X nysub = 4;
- X } else {
- X ytick = V_YTick.val_u.udt_interval.int_lo;
- X nysub = V_YTick.val_u.udt_interval.int_hi;
- X }
- X rtick = XisAngular? ytick : xtick;
- X atick = XisAngular? xtick : ytick;
- X nasub = XisAngular? nxsub : nysub;
- X nrsub = XisAngular? nysub : nxsub;
- X amax = InRadians? 2.0 * pi : 360.0;
- X
- X /* Axis options */
- X if (VtoBoolean(V_Gridding)) {
- X /* draw circles */
- X plstyl(0, &mark1, space1);
- X /* circular ticks */
- X for (i=0,r=(rtick/nrsub); r<rmax; r += (rtick/nrsub),i++) {
- X da = i%nrsub? 0.05 * atick : 0.1 * atick;
- X for (ang=0; ang<amax; ang += atick) {
- X x0 = r * cos(InRadians? ang-da : DTR(ang-da));
- X y0 = r * sin(InRadians? ang-da : DTR(ang-da));
- X xn = r * cos(InRadians? ang+da : DTR(ang+da));
- X yn = r * sin(InRadians? ang+da : DTR(ang+da));
- X pljoin(x0,y0,xn,yn);
- X }
- X }
- X#ifdef CIRCULAR_TICKS
- X /* major circles */
- X for (r=rtick; r<rmax; r += rtick) {
- X x0 = r; y0 = 0.0;
- X for (ang=1.0; ang<=360.0; ang++) {
- X xn = r * cos((double)(DTR(ang)));
- X yn = r * sin((double)(DTR(ang)));
- X pljoin(x0,y0,xn,yn);
- X x0 = xn; y0 = yn;
- X }
- X }
- X#endif
- X /* draw spokes */
- X for (i=0,ang=0.0; ang<amax; ang += (atick/nasub),i++) {
- X xn = rmax * cos(InRadians? ang : DTR(ang));
- X yn = rmax * sin(InRadians? ang : DTR(ang));
- X if (i%nasub == 0) {
- X pljoin((FLOAT)0.0,(FLOAT)0.0,xn,yn);
- X } else {
- X pljoin(xn,yn,1.05*xn,1.05*yn);
- X }
- X }
- X }
- X /* write angle labels */
- X plschr(0., VtoDbl(V_AnnotationScale));
- X j = amax / atick;
- X for (ang=0.0,i=0; i<j; ang += atick,i++) {
- X if (InRadians) {
- X xn = rmax * cos((double)ang);
- X yn = rmax * sin((double)ang);
- X if (fabs(ang-(2.0*pi)) > 1.0e-2)
- X sprintf(s, "%.2f #gp", (float)ang/pi);
- X } else {
- X xn = rmax * cos((double)DTR(ang));
- X yn = rmax * sin((double)DTR(ang));
- X sprintf(s, "%d", (int)(ang+0.5));
- X }
- X if (xn >= 0)
- X plptex(xn,yn,xn,yn,-0.15, s);
- X else
- X plptex(xn,yn,-xn,-yn,1.15, s);
- X }
- X plstyl(0, &mark0, &space0);
- X
- X /* plot curves */
- X if ((A = (FLOAT *)calloc(NTuples, sizeof(FLOAT))) == (FLOAT *)NULL) {
- X perror("(Plot2D) ");
- X ErrorExit();
- X }
- X if ((R = (FLOAT *)calloc(NTuples, sizeof(FLOAT))) == (FLOAT *)NULL) {
- X perror("(Plot2D) ");
- X ErrorExit();
- X }
- X if (VtoBoolean(V_SupplyAbscissa)) {
- X for (i=0; i<NTuples; i++)
- X if (XisAngular)
- X A[i] = i*2.0*pi/(NTuples-1);
- X else
- X R[i] = i*rmax/(NTuples-1);
- X } else {
- X for (i=0; i<NTuples; i++)
- X if (XisAngular)
- X A[i] = InRadians? Data[i][0] : DTR(Data[i][0]);
- X else
- X R[i] = Data[i][0];
- X }
- X for (i=1; i<TupleSize; i++) {
- X if (NLineStyles > 0) {
- X /* use user-supplied patterns */
- X plstyl(
- X LineStyles[(i-1)%NLineStyles].ls_nelms,
- X LineStyles[(i-1)%NLineStyles].ls_mark,
- X LineStyles[(i-1)%NLineStyles].ls_space
- X );
- X } else {
- X pllsty((i-1)%8);
- X }
- X plcol(i);
- X
- X /* get and convert data if necessary */
- X if (InRadians && !XisAngular)
- X for (j=0; j<NTuples; j++)
- X A[j] = Data[j][i];
- X else if ((!InRadians) && !XisAngular)
- X for (j=0; j<NTuples; j++)
- X A[j] = DTR(Data[j][i]);
- X else
- X for (j=0; j<NTuples; j++)
- X R[j] = Data[j][i];
- X
- X /* convert to cartesian A<->X R<->Y*/
- X for (j=0; j<NTuples; j++) {
- X x0 = R[j] * cos(A[j]);
- X y0 = R[j] * sin(A[j]);
- X A[j] = x0;
- X R[j] = y0;
- X }
- X if (VtoBoolean(V_PlotJoined)) {
- X x0 = A[0];
- X y0 = R[0];
- X for (j=1; j<NTuples; j++) {
- X pljoin(A[j-1], R[j-1], A[j],R[j]);
- X }
- X }
- X
- X if (VtoBoolean(V_PlotPoints)) {
- X plschr(0., VtoDbl(V_PointScale));
- X pllsty(1);
- X if (NPointCodes > 0) {
- X plpoin(NTuples, A, R, PointCodes[(i-1)%NPointCodes]);
- X } else {
- X plpoin(NTuples, A, R, i);
- X }
- X }
- X }
- X
- X /* restore line styles etc... */
- X pllsty(1);
- X plcol(1);
- X plschr(0., VtoDbl(V_LabelScale));
- X pllab(VtoString(V_XLabel), VtoString(V_YLabel), "");
- X plschr(0., VtoDbl(V_TitleScale));
- X pllab("","", VtoString(V_PlotTitle));
- X}
- X
- X
- Xvoid
- XStatisticsOfX(Data, NTuples,TupleSize, Median, StdDev)
- XFLOAT **Data;
- Xint NTuples;
- Xint TupleSize;
- XFLOAT *Median;
- XFLOAT *StdDev;
- X{
- X#ifdef ANSI_C
- X FLOAT MedianOfX();
- X FLOAT StdDevOfX();
- X/*debug
- X FLOAT MedianOfX(FLOAT **Data,int NTuples,int TupleSize);
- X FLOAT StdDevOfX(FLOAT **Data,int NTuples,int TupleSize);
- Xdebug*/
- X#else
- X FLOAT MedianOfX();
- X FLOAT StdDevOfX();
- X#endif
- X *StdDev = StdDevOfX(Data,NTuples,TupleSize);
- X *Median = MedianOfX(Data,NTuples,TupleSize);
- X}
- X
- X
- Xvoid
- XStatisticsOfY(Data, NTuples,TupleSize, Median, StdDev)
- XFLOAT **Data;
- Xint NTuples;
- Xint TupleSize;
- XFLOAT *Median;
- XFLOAT *StdDev;
- X{
- X#ifdef ANSI_C
- X FLOAT MedianOfY();
- X FLOAT StdDevOfY();
- X/*debug
- X FLOAT MedianOfY(FLOAT **Data,int NTuples,int TupleSize);
- X FLOAT StdDevOfY(FLOAT **Data,int NTuples,int TupleSize);
- Xdebug*/
- X#else
- X FLOAT MedianOfY();
- X FLOAT StdDevOfY();
- X#endif
- X *StdDev = StdDevOfY(Data,NTuples,TupleSize);
- X *Median = MedianOfY(Data,NTuples,TupleSize);
- X}
- X
- X
- XFLOAT
- XStdDevOfX(Data,NTuples,TupleSize)
- XFLOAT **Data;
- Xint NTuples;
- Xint TupleSize;
- X{
- X int i;
- X FLOAT StdDev, x;
- X FLOAT var, sum, mean;
- X double sqrt(), fabs();
- X
- X if (VtoBoolean(V_SupplyAbscissa)) {
- X return((FLOAT)(NTuples*NTuples)/12.0);
- X }
- X
- X sum = 0.0;
- X for (i=0; i<NTuples; i++)
- X sum += Data[i][0];
- X mean = sum / NTuples;
- X
- X var = 0.0;
- X for (i=0; i<NTuples; i++) {
- X x = fabs((double)(Data[i][0] - mean));
- X var += x * x;
- X }
- X var /= (NTuples-1);
- X StdDev = sqrt((double)var);
- X return(StdDev);
- X}
- X
- X
- XFLOAT
- XStdDevOfY(Data,NTuples,TupleSize)
- XFLOAT **Data;
- Xint NTuples;
- Xint TupleSize;
- X{
- X int i,j,D;
- X FLOAT StdDev, x;
- X FLOAT var, sum, mean;
- X FLOAT n;
- X double sqrt(), fabs();
- X
- X D = VtoBoolean(V_SupplyAbscissa) ? 0 : 1;
- X n = NTuples * (TupleSize-D);
- X sum = 0.0;
- X for (i=0; i<NTuples; i++)
- X for (j=D; j<TupleSize; j++) {
- X sum += Data[i][j];
- X }
- X mean = sum / n;
- X
- X var = 0.0;
- X for (i=0; i<NTuples; i++)
- X for (j=D; j<TupleSize; j++) {
- X x = fabs((double)(Data[i][j] - mean));
- X var += x * x;
- X }
- X var /= (n-1);
- X StdDev = sqrt((double)var);
- X return(StdDev);
- X}
- X
- X#define BIG 1.0e30
- X#define AFAC 1.5
- X#define AMP 1.5
- X
- XFLOAT
- XMedianOfX(Data,NTuples,TupleSize)
- XFLOAT **Data;
- Xint NTuples;
- Xint TupleSize;
- X/* an iterative computation of the median...
- X * Code taken from Numerical Recipes..
- X */
- X{
- X int np, nm, i;
- X FLOAT xx,xp,xm,sumx,sum,eps,stemp,dum,ap,am,aa,a;
- X FLOAT Median;
- X double fabs();
- X
- X if (VtoBoolean(V_SupplyAbscissa))
- X return((FLOAT)(0.5*NTuples));
- X
- X /* first estimate */
- X a = 0.5 * (Data[0][0] + Data[NTuples-1][0]);
- X eps = fabs((double)(Data[NTuples-1][0] - Data[0][0]));
- X
- X am = -(ap=BIG);
- X for (;;) {
- X sum = sumx = 0.0;
- X np = nm = 0; /* # point above and below median */
- X xm = -(xp = BIG);
- X
- X for (i=0; i<NTuples; i++) {
- X xx = Data[i][0];
- X if (xx != a) {
- X if (xx > a) {
- X ++np;
- X if (xx < xp) xp = xx;
- X } else if (xx < a) {
- X ++nm;
- X if (xx > xm) xm = xx;
- X }
- X sum += dum=1.0/(eps+fabs((double)(xx-a)));
- X sumx += xx * dum;
- X }
- X }
- X
- X stemp = (sumx / sum) - a;
- X if ((np-nm) >= 2) {
- X /* guess is too low make another pass */
- X am = a;
- X aa = stemp < 0.0? xp : xp + stemp*AMP;
- X if (aa > ap) aa = 0.5*(a+ap);
- X eps = AFAC * fabs((double)(aa-a));
- X a = aa;
- X } else if ((nm-np) >= 2) {
- X /* guess is too high make another pass */
- X ap = a;
- X aa = stemp > 0.0? xm : xm+stemp*AMP;
- X if (aa < am) aa = 0.5*(a+am);
- X eps = AFAC*fabs((double)(aa-a));
- X a = aa;
- X } else { /* got it */
- X if (NTuples%2 == 0) {
- X Median = 0.5*(np==nm? xp+xm : np>nm? a+xp : xm+a);
- X } else {
- X Median = np == nm? a : np>nm? xp : xm;
- X }
- X return(Median);
- X }
- X }
- X}
- X
- XFLOAT
- XMedianOfY(Data,N,M)
- XFLOAT **Data;
- Xint N;
- Xint M;
- X/* an iterative computation of the median...
- X * Code taken from Numerical Recipes..
- X */
- X{
- X int n, np, nm, i,j,D;
- X FLOAT xx,xp,xm,sumx,sum,eps,stemp,dum,ap,am,aa,a;
- X FLOAT Median;
- X double fabs();
- X
- X D = VtoBoolean(V_SupplyAbscissa) ? 0 : 1;
- X n = N * (M-D);
- X
- X /* first estimate */
- X a = 0.5 * (Data[0][D] + Data[N-1][M-1]);
- X eps = fabs((double)(Data[N-1][M-1] - Data[0][D]));
- X
- X am = -(ap=BIG);
- X for (;;) {
- X sum = sumx = 0.0;
- X np = nm = 0; /* # point above and below median */
- X xm = -(xp = BIG);
- X
- X for (i=0; i<N; i++) {
- X for (j=D; j<M; j++) {
- X xx = Data[i][j];
- X if (xx != a) {
- X if (xx > a) {
- X ++np;
- X if (xx < xp) xp = xx;
- X } else if (xx < a) {
- X ++nm;
- X if (xx > xm) xm = xx;
- X }
- X sum += dum=1.0/(eps+fabs((double)(xx-a)));
- X sumx += xx * dum;
- X }
- X }
- X }
- X
- X stemp = (sumx / sum) - a;
- X if ((np-nm) >= 2) {
- X /* guess is too low make another pass */
- X am = a;
- X aa = stemp < 0.0? xp : xp + stemp*AMP;
- X if (aa > ap) aa = 0.5*(a+ap);
- X eps = AFAC * fabs((double)(aa-a));
- X a = aa;
- X } else if ((nm-np) >= 2) {
- X /* guess is too high make another pass */
- X ap = a;
- X aa = stemp > 0.0? xm : xm+stemp*AMP;
- X if (aa < am) aa = 0.5*(a+am);
- X eps = AFAC*fabs((double)(aa-a));
- X a = aa;
- X } else { /* got it */
- X if (n%2 == 0) {
- X Median = 0.5*(np==nm? xp+xm : np>nm? a+xp : xm+a);
- X } else {
- X Median = np == nm? a : np>nm? xp : xm;
- X }
- X return(Median);
- X }
- X }
- X}
- END_OF_FILE
- if test 25452 -ne `wc -c <'Csrc/plotting.c'`; then
- echo shar: \"'Csrc/plotting.c'\" unpacked with wrong size!
- fi
- chmod +x 'Csrc/plotting.c'
- # end of 'Csrc/plotting.c'
- fi
- echo shar: End of archive 3 \(of 3\).
- cp /dev/null ark3isdone
- MISSING=""
- for I in 1 2 3 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 3 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
- Mail comments to the moderator at <amiga-request@uunet.uu.net>.
- Post requests for sources, and general discussion to comp.sys.amiga.
-